/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package client.controllers;

import client.data.Positie;
import client.gui.*;
import java.util.Vector;
import javax.swing.DefaultListModel;

/**
 *
 * @author 
 */
public class BackTracking {
    
    private int diepte,woordlengte;
    private Vector deeloplossing;
    private Positie currentPositie;
    private String woord;
    private Positie[][] bord;
    private boolean geenVolgendeLetter,woordGevonden;
    private BoggleClient bc;
    
    
    public BackTracking(String woord,Positie[][] bord){
        System.out.println("Nieuwe Backtracking gestart met woord: "+woord);
        diepte = 0;
        this.woord = woord;
        this.bord = bord;
        this.woordlengte = woord.length();
        woordGevonden = false;
        geenVolgendeLetter = false;
        deeloplossing = new Vector();
        deeloplossing.clear();
        for(int i=0; i < 4; i++){
            for(int j=0; j<4; j++){
                bord[i][j].setOntdekt(false);
            }
        }
    }
    
    //geefverdere: geef verzameling verderzettingen van de deeloplossing.
    private Vector geefverdere(Positie p,String nextLetter){
        Vector mogelijke = new Vector();
        mogelijke.clear();
        for(int i = -1; i < 2; i++){
            for(int j = -1; j < 2; j++){
                if(p.getRij()+i >= 0 && p.getRij()+i < 4 && p.getKolom()+j >= 0 && p.getKolom()+j < 4){
                    if(!bord[p.getRij()+i][p.getKolom()+j].isOntdekt()
                        && bord[p.getRij()+i][p.getKolom()+j].getLetter().equals(nextLetter)){
                        mogelijke.add(bord[p.getRij()+i][p.getKolom()+j]);
                    }
                }
            }
        }
        if(mogelijke.size()==0){
            System.out.println("geen mogelijke oplossingen meer voor letter "+nextLetter);
            geenVolgendeLetter = true;
        }else{
            for(int i=0; i < mogelijke.size();i++){
                System.out.println("rij:"+((Positie)mogelijke.elementAt(i)).getRij()+" kolom:"+((Positie)mogelijke.elementAt(i)).getKolom()+" letter:"+((Positie)(mogelijke.get(i))).getLetter());
            }
        }
        return mogelijke;
    }
    
    //als opgeroepen met zoekalle=true worden alle oplossingen gezocht
    public void losop(){
        geenVolgendeLetter=false;
        if(woord.length() > 0){
            String nextLetter = ""+woord.charAt(0);
            losop(nextLetter);
        }else
            System.out.println("het meegegeven woord was leeg.");
    }
    private void losop(String nextLetter){
//bij sommige problemen kan een oplossing nog verlengd worden tot een langere oplossing
//daarom moet het volgend stuk code ook worden uitgevoerd als we een oplossing hebben.
        System.out.println("De te zoeken Letter: "+nextLetter);
        Vector mogelijk;
        if (diepte == 0) {
            mogelijk = geefStartPosities(nextLetter);
        } else {
            mogelijk = geefverdere(currentPositie, nextLetter);
        }
        if (!geenVolgendeLetter && !woordGevonden) {
            diepte++;
            deeloplossing.setSize(diepte);//lengte aanpassen voor extra knoop.
            int i = 0;
            while (!woordGevonden && i < mogelijk.size()) {
                currentPositie = (Positie) mogelijk.get(i);
                System.out.println("currentPositie: "+currentPositie.getRij()+" : "+currentPositie.getKolom());
                bord[currentPositie.getRij()][currentPositie.getKolom()].setOntdekt(true);
                deeloplossing.add(diepte - 1,currentPositie);
                if (diepte < woord.length()) {
                    losop("" + woord.charAt(diepte));
                    bord[currentPositie.getRij()][currentPositie.getKolom()].setOntdekt(false);
                } else if (diepte == woord.length()) {
                    woordGevonden = true;
                }
                i++;
            }
            diepte--;
            deeloplossing.setSize(diepte);
        }
        if(geenVolgendeLetter && diepte > 0){
                System.out.println("Geen volgende Letter gevonden");
                geenVolgendeLetter = false;

        }
        if(diepte == 0 && !woordGevonden){
                DefaultListModel l = bc.getListModel();
                l.removeElement(woord);
                bc.setLijst(l);
                System.out.println("woord moet uit lijst verwijderd worden");
        }
                
    }

    private Vector geefStartPosities(String nextLetter) {
        Vector mogelijke=new Vector();
        mogelijke.clear();
        for(int i = 0; i < 4; i++){
            for(int j = 0; j < 4; j++){
                if(bord[i][j].getLetter().equals(nextLetter)){
                    mogelijke.add(bord[i][j]);
                }
            }
        }
        if(mogelijke.size() < 1){
            System.out.println("geen mogelijke oplossingen meer voor letter "+nextLetter);
            geenVolgendeLetter = true;
        }else{
            for(int i=0; i < mogelijke.size();i++){
                System.out.println("rij:"+((Positie)mogelijke.elementAt(i)).getRij()+" kolom:"+((Positie)mogelijke.elementAt(i)).getKolom()+" letter:"+((Positie)(mogelijke.get(i))).getLetter());
            }
        }
        return mogelijke;
    }

    public BoggleClient getBc() {
        return bc;
    }

    public void setBc(BoggleClient bc) {
        this.bc = bc;
    }
}
